home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 5_2007-2008.ISO / data / Zips / DTMF_detec20367512102006.psc / DTMF Detector / WaveInRecorder.cls < prev   
Text File  |  2006-12-10  |  64KB  |  1,506 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "WaveInRecorder"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. Option Explicit
  15.  
  16. ' WaveInRecorder (VB 6)
  17. '
  18. ' Records audio signal from WaveIn.
  19. ' Mixer line to record from can be selected,
  20. ' its volume can be changed.
  21. ' Buffercount/size can be modified.
  22. ' Uses In-Class subclassing by Paul Caton (PSC).
  23.  
  24. Private Declare Function GetModuleHandleA Lib "kernel32" ( _
  25.     ByVal lpModuleName As String _
  26. ) As Long
  27.  
  28. Private Declare Function GetProcAddress Lib "kernel32" ( _
  29.     ByVal hModule As Long, _
  30.     ByVal lpProcName As String _
  31. ) As Long
  32.  
  33. Private Declare Function IsBadReadPtr Lib "kernel32" ( _
  34.     ptr As Any, _
  35.     ByVal ucb As Long _
  36. ) As Long
  37.  
  38. Private Declare Function IsBadCodePtr Lib "kernel32" ( _
  39.     ByVal lpfn As Long _
  40. ) As Long
  41.  
  42. Private Declare Function GetWindowThreadProcessId Lib "user32" ( _
  43.     ByVal hWnd As Long, _
  44.     lpdwProcessId As Long _
  45. ) As Long
  46.  
  47. Private Declare Function GetCurrentProcessId Lib "kernel32" ( _
  48. ) As Long
  49.  
  50. Private Declare Function IsWindow Lib "user32" ( _
  51.     ByVal hWnd As Long _
  52. ) As Long
  53.  
  54. Private Declare Function CallWindowProcA Lib "user32" ( _
  55.     ByVal lpPrevWndFunc As Long, _
  56.     ByVal hWnd As Long, _
  57.     ByVal Msg As Long, _
  58.     ByVal wParam As Long, _
  59.     ByVal lParam As Long _
  60. ) As Long
  61.  
  62. Private Declare Function CreateWindowEx Lib "user32" _
  63. Alias "CreateWindowExA" ( _
  64.     ByVal dwExStyle As Long, _
  65.     ByVal lpClassName As String, _
  66.     ByVal lpWindowName As String, _
  67.     ByVal dwStyle As Long, _
  68.     ByVal x As Long, _
  69.     ByVal y As Long, _
  70.     ByVal nWidth As Long, _
  71.     ByVal nHeight As Long, _
  72.     ByVal hWndParent As Long, _
  73.     ByVal hMenu As Long, _
  74.     ByVal hInstance As Long, _
  75.     ByVal lpParam As Long _
  76. ) As Long
  77.  
  78. Private Declare Function DestroyWindow Lib "user32" ( _
  79.     ByVal hWnd As Long _
  80. ) As Long
  81.  
  82. Private Declare Sub ZeroMem Lib "kernel32.dll" _
  83. Alias "RtlZeroMemory" ( _
  84.     pDst As Any, _
  85.     ByVal cBytes As Long _
  86. )
  87.  
  88. Private Declare Function VirtualFree Lib "kernel32" ( _
  89.     ByVal lpAddress As Long, _
  90.     ByVal dwSize As Long, _
  91.     ByVal dwFreeType As Long _
  92. ) As Long
  93.  
  94. Private Declare Function VirtualAlloc Lib "kernel32" ( _
  95.     ByVal lpAddress As Long, _
  96.     ByVal dwSize As Long, _
  97.     ByVal flAllocationType As Long, _
  98.     ByVal flProtect As Long _
  99. ) As Long
  100.  
  101. Private Declare Function GlobalUnlock Lib "kernel32" ( _
  102.     ByVal hMem As Long _
  103. ) As Long
  104.  
  105. Private Declare Function GlobalAlloc Lib "kernel32" ( _
  106.     ByVal wFlags As GMEMFlags, _
  107.     ByVal dwBytes As Long _
  108. ) As Long
  109.  
  110. Private Declare Function GlobalFree Lib "kernel32" ( _
  111.     ByVal hMem As Long _
  112. ) As Long
  113.  
  114. Private Declare Function GlobalLock Lib "kernel32" ( _
  115.     ByVal hMem As Long _
  116. ) As Long
  117.  
  118. Private Declare Function SetWindowLong Lib "user32" _
  119. Alias "SetWindowLongA" ( _
  120.     ByVal hWnd As Long, _
  121.     ByVal nIndex As Long, _
  122.     ByVal dwNewLong As Long _
  123. ) As Long
  124.  
  125. Private Declare Sub CpyMem Lib "kernel32" _
  126. Alias "RtlMoveMemory" ( _
  127.     pDst As Any, _
  128.     pSrc As Any, _
  129.     ByVal cBytes As Long _
  130. )
  131.  
  132. Private Declare Function waveInAddBuffer Lib "winmm" ( _
  133.     ByVal hwi As Long, _
  134.     pwh As Any, _
  135.     ByVal cbwh As Long _
  136. ) As Long
  137.  
  138. Private Declare Function waveInClose Lib "winmm" ( _
  139.     ByVal hwi As Long _
  140. ) As Long
  141.  
  142. Private Declare Function waveInGetDevCaps Lib "winmm" _
  143. Alias "waveInGetDevCapsA" ( _
  144.     ByVal hwi As Long, _
  145.     pwic As Any, _
  146.     ByVal cbwic As Long _
  147. ) As Long
  148.  
  149. Private Declare Function waveInGetErrorText Lib "winmm" _
  150. Alias "waveInGetErrorTextA" ( _
  151.     ByVal mmrError As Long, _
  152.     ByVal pszText As String, _
  153.     ByVal cchText As Long _
  154. ) As Long
  155.  
  156. Private Declare Function waveInGetID Lib "winmm" ( _
  157.     ByVal hwi As Long, _
  158.     puDeviceID As Long _
  159. ) As Long
  160.  
  161. Private Declare Function waveInGetNumDevs Lib "winmm" ( _
  162. ) As Long
  163.  
  164. Private Declare Function waveInGetPosition Lib "winmm" ( _
  165.     ByVal hwi As Long, _
  166.     pmmt As Any, _
  167.     ByVal cbmmt As Long _
  168. ) As Long
  169.  
  170. Private Declare Function waveInMessage Lib "winmm" ( _
  171.     ByVal deviceid As Long, _
  172.     ByVal uMsg As Long, _
  173.     ByVal dwParam1 As Long, _
  174.     ByVal dwParam2 As Long _
  175. ) As Long
  176.  
  177. Private Declare Function waveInOpen Lib "winmm" ( _
  178.     phwi As Long, _
  179.     ByVal uDeviceID As Long, _
  180.     pwfx As Any, _
  181.     ByVal dwCallback As Long, _
  182.     ByVal dwCallbackInstance As Long, _
  183.     ByVal fdwOpen As Long _
  184. ) As Long
  185.  
  186. Private Declare Function waveInPrepareHeader Lib "winmm" ( _
  187.     ByVal hwi As Long, _
  188.     pwh As Any, _
  189.     ByVal cbwh As Long _
  190. ) As Long
  191.  
  192. Private Declare Function waveInUnprepareHeader Lib "winmm.dll" ( _
  193.     ByVal hWaveIn As Long, _
  194.     lpWaveInHdr As Any, _
  195.     ByVal uSize As Long _
  196. ) As Long
  197.  
  198. Private Declare Function waveInReset Lib "winmm" ( _
  199.     ByVal hwi As Long _
  200. ) As Long
  201.  
  202. Private Declare Function waveInStart Lib "winmm" ( _
  203.     ByVal hwi As Long _
  204. ) As Long
  205.  
  206. Private Declare Function waveInStop Lib "winmm" ( _
  207.     ByVal hwi As Long _
  208. ) As Long
  209.  
  210. Private Declare Function mixerClose Lib "winmm" ( _
  211.     ByVal hmx As Long _
  212. ) As Long
  213.  
  214. Private Declare Function mixerOpen Lib "winmm" ( _
  215.     phmx As Long, _
  216.     ByVal uMxId As Long, _
  217.     ByVal dwCallback As Long, _
  218.     ByVal dwInstance As Long, _
  219.     ByVal fdwOpen As Long _
  220. ) As Long
  221.  
  222. Private Declare Function mixerGetControlDetails Lib "winmm" _
  223. Alias "mixerGetControlDetailsA" ( _
  224.     ByVal hmxobj As Long, _
  225.     pmxcd As MIXERCONTROLDETAILS, _
  226.     ByVal fdwDetails As Long _
  227. ) As Long
  228.  
  229. Private Declare Function mixerGetLineControls Lib "winmm" _
  230. Alias "mixerGetLineControlsA" ( _
  231.     ByVal hmxobj As Long, _
  232.     pmxlc As MIXERLINECONTROLS, _
  233.     ByVal fdwControls As Long _
  234. ) As Long
  235.  
  236. Private Declare Function mixerGetLineInfo Lib "winmm" _
  237. Alias "mixerGetLineInfoA" ( _
  238.     ByVal hmxobj As Long, _
  239.     pmxl As MIXERLINE, _
  240.     ByVal fdwInfo As Long _
  241. ) As Long
  242.  
  243. Private Declare Function mixerSetControlDetails Lib "winmm" ( _
  244.     ByVal hmxobj As Long, _
  245.     pmxcd As MIXERCONTROLDETAILS, _
  246.     ByVal fdwDetails As Long _
  247. ) As Long
  248.  
  249. Private Declare Function mixerGetDevCaps Lib "winmm" _
  250. Alias "mixerGetDevCapsA" ( _
  251.     ByVal uMxId As Long, _
  252.     pmxcaps As MIXERCAPS, _
  253.     ByVal cbmxcaps As Long _
  254. ) As Long
  255.  
  256. ' of course there are a lot more line ids
  257. Public Enum MIXER_RECORDING_LINES
  258.     MIXERLINE_ANALOG = &H100A&
  259.     MIXERLINE_AUXILIARY = &H1009&
  260.     MIXERLINE_COMPACTDISC = &H1005&
  261.     MIXERLINE_DIGITAL = &H1001&
  262.     MIXERLINE_LINE = &H1002&
  263.     MIXERLINE_MICROPHONE = &H1003&
  264.     MIXERLINE_PCSPEAKER = &H1007&
  265.     MIXERLINE_SYNTHESIZER = &H1004&
  266.     MIXERLINE_TELEPHONE = &H1006&
  267.     MIXERLINE_UNDEFINED = &H1000&
  268.     MIXERLINE_WAVEOUT = &H1008&
  269. End Enum
  270.  
  271. Private Enum GMEMFlags
  272.     GMEM_FIXED = &H0
  273.     GMEM_MOVEABLE = &H2
  274.     GMEM_ZEROINIT = &H40
  275. End Enum
  276.  
  277. ' cSelfSub stuff
  278. Private Enum eMsgWhen                               ' When to callback
  279.     MSG_BEFORE = 1                                  ' Callback before the original WndProc
  280.     MSG_AFTER = 2                                   ' Callback after the original WndProc
  281.     MSG_BEFORE_AFTER = MSG_BEFORE Or MSG_AFTER      ' Callback before and after the original WndProc
  282. End Enum
  283.  
  284. Private Const ALL_MESSAGES  As Long = -1            ' All messages callback
  285. Private Const MSG_ENTRIES   As Long = 32            ' Number of msg table entries
  286. Private Const WNDPROC_OFF   As Long = &H38          ' Thunk offset to the WndProc execution address
  287. Private Const GWL_WNDPROC   As Long = -4            ' SetWindowsLong WndProc index
  288. Private Const IDX_SHUTDOWN  As Long = 1             ' Thunk data index of the shutdown flag
  289. Private Const IDX_HWND      As Long = 2             ' Thunk data index of the subclassed hWnd
  290. Private Const IDX_WNDPROC   As Long = 9             ' Thunk data index of the original WndProc
  291. Private Const IDX_BTABLE    As Long = 11            ' Thunk data index of the Before table
  292. Private Const IDX_ATABLE    As Long = 12            ' Thunk data index of the After table
  293. Private Const IDX_PARM_USER As Long = 13            ' Thunk data index of the User-defined callback parameter data index
  294.  
  295. Private z_ScMem             As Long                 ' Thunk base address
  296. Private z_Sc(64)            As Long                 ' Thunk machine-code initialised here
  297. Private z_Funk              As Collection           ' hWnd/thunk-address collection
  298. ' end cSelfSub stuff
  299.  
  300. Private Const WAVE_FORMAT_PCM                           As Long = 1&
  301.  
  302. Private Const MAXPNAMELEN                               As Long = 32&
  303.  
  304. Private Const MIXER_GETCONTROLDETAILSF_LISTTEXT         As Long = &H1&
  305. Private Const MIXER_GETCONTROLDETAILSF_VALUE            As Long = &H0&
  306.  
  307. Private Const MIXER_GETLINECONTROLSF_ONEBYTYPE          As Long = &H2&
  308.     
  309. Private Const MIXER_GETLINEINFOF_COMPONENTTYPE          As Long = &H3&
  310. Private Const MIXER_GETLINEINFOF_LINEID                 As Long = &H2&
  311. Private Const MIXER_GETLINEINFOF_SOURCE                 As Long = &H1&
  312. Private Const MIXER_GETLINEINFOF_DESTINATION            As Long = &H0&
  313.  
  314. Private Const MIXER_LONG_NAME_CHARS                     As Long = 64
  315. Private Const MIXER_SHORT_NAME_CHARS                    As Long = 16
  316.  
  317. Private Const MIXERCONTROL_CONTROLTYPE_VOLUME           As Long = &H50030001
  318. Private Const MIXERCONTROL_CONTROLTYPE_MUTE             As Long = &H20010002
  319.  
  320. Private Const MIXER_SETCONTROLDETAILSF_VALUE            As Long = &H0&
  321.  
  322. Private Const MIXER_OBJECTF_WAVEIN                      As Long = &H20000000
  323.  
  324. Private Const MIXERCONTROL_CT_UNITS_BOOLEAN             As Long = &H10000
  325. Private Const MIXERCONTROL_CT_SC_LIST_MULTIPLE          As Long = &H1000000
  326. Private Const MIXERCONTROL_CT_SC_LIST_SINGLE            As Long = 0&
  327. Private Const MIXERCONTROL_CT_CLASS_LIST                As Long = &H70000000
  328.  
  329. Private Const MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT   As Long = (MIXERCONTROL_CT_CLASS_LIST Or MIXERCONTROL_CT_SC_LIST_MULTIPLE Or MIXERCONTROL_CT_UNITS_BOOLEAN)
  330. Private Const MIXERCONTROL_CONTROLTYPE_SINGLESELECT     As Long = (MIXERCONTROL_CT_CLASS_LIST Or MIXERCONTROL_CT_SC_LIST_SINGLE Or MIXERCONTROL_CT_UNITS_BOOLEAN)
  331.  
  332. Private Const MIXERCONTROL_CONTROLTYPE_MIXER            As Long = (MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT + 1)
  333. Private Const MIXERCONTROL_CONTROLTYPE_MUX              As Long = (MIXERCONTROL_CONTROLTYPE_SINGLESELECT + 1)
  334.  
  335. Private Const MIXERLINE_COMPONENTTYPE_DST_WAVEIN        As Long = &H7&
  336.  
  337. Private Const CALLBACK_WINDOW                           As Long = &H10000
  338.  
  339. Private Const MM_WIM_OPEN                               As Long = &H3BE
  340. Private Const MM_WIM_CLOSE                              As Long = &H3BF
  341. Private Const MM_WIM_DATA                               As Long = &H3C0
  342.  
  343. Private Const WM_DESTROY                                As Long = &H2&
  344. Private Const MMSYSERR_NOERROR                          As Long = 0&
  345.  
  346. Private Type MIXERCONTROLDETAILS_LISTTEXT
  347.     dwParam1                                    As Long
  348.     dwParam2                                    As Long
  349.     szName                                      As Long
  350. End Type
  351.  
  352. Private Type MIXERCONTROL
  353.     cbStruct                                    As Long
  354.     dwControlID                                 As Long
  355.     dwControlType                               As Long
  356.     fdwControl                                  As Long
  357.     cMultipleItems                              As Long
  358.     szShortName(MIXER_SHORT_NAME_CHARS / 2 - 1) As Integer
  359.     szName(MIXER_LONG_NAME_CHARS / 2 - 1)       As Integer
  360.     Bounds(5)                                   As Long
  361.     Metrics(5)                                  As Long
  362. End Type
  363.  
  364. Private Type MIXERCONTROLDETAILS
  365.     cbStruct                                    As Long
  366.     dwControlID                                 As Long
  367.     cChannels                                   As Long
  368.     item                                        As Long
  369.     cbDetails                                   As Long
  370.     paDetails                                   As Long
  371. End Type
  372.  
  373. Private Type Target
  374.     dwType                                      As Long
  375.     dwDeviceID                                  As Long
  376.     wMid                                        As Integer
  377.     wPid                                        As Integer
  378.     vDriverVersion                              As Long
  379.     szPname                                     As String * MAXPNAMELEN
  380. End Type
  381.  
  382. Private Type MIXERLINE
  383.     cbStruct                                    As Long
  384.     dwDestination                               As Long
  385.     dwSource                                    As Long
  386.     dwLineID                                    As Long
  387.     fdwLine                                     As Long
  388.     dwUser                                      As Long
  389.     dwComponentType                             As Long
  390.     cChannels                                   As Long
  391.     cConnections                                As Long
  392.     cControls                                   As Long
  393.     szShortName                                 As String * MIXER_SHORT_NAME_CHARS
  394.     szName                                      As String * MIXER_LONG_NAME_CHARS
  395.     tTarget                                     As Target
  396. End Type
  397.  
  398. Private Type MIXERLINECONTROLS
  399.     cbStruct                                    As Long
  400.     dwLineID                                    As Long
  401.     dwControl                                   As Long
  402.     cControls                                   As Long
  403.     cbmxctrl                                    As Long
  404.     pamxctrl                                    As Long
  405. End Type
  406.  
  407. Private Type MIXERCAPS
  408.     wMid                                        As Integer
  409.     wPid                                        As Integer
  410.     vDriverVersion                              As Long
  411.     szPname                                     As String * 32
  412.     fdwSupport                                  As Long
  413.     cDestinations                               As Long
  414. End Type
  415.  
  416. Private Type MIXERCONTROLDETAILS_BOOLEAN
  417.      fValue                                     As Long
  418. End Type
  419.  
  420. Private Type volume_stereo
  421.     L                                           As Long
  422.     R                                           As Long
  423. End Type
  424.  
  425. Private Type WAVEFORMATEX
  426.     wFormatTag                                  As Integer
  427.     nChannels                                   As Integer
  428.     nSamplesPerSec                              As Long
  429.     nAvgBytesPerSec                             As Long
  430.     nBlockAlign                                 As Integer
  431.     wBitsPerSample                              As Integer
  432.     cbSize                                      As Integer
  433. End Type
  434.  
  435. Private Type WAVEHDR
  436.     lpData                                      As Long
  437.     dwBufferLen                                 As Long
  438.     dwBytesRec                                  As Long
  439.     dwUser                                      As Long
  440.     dwFlags                                     As Long
  441.     dwLoops                                     As Long
  442.     lpNext                                      As Long
  443.     reserved                                    As Long
  444. End Type
  445.  
  446. Private Type WAVEFORMAT
  447.     wFormatTag                                  As Integer
  448.     nChannels                                   As Integer
  449.     nSamplesPerSec                              As Long
  450.     nAvgBytesPerSec                             As Long
  451.     nBlockAlign                                 As Integer
  452. End Type
  453.  
  454. Private Type WAVEINCAPS
  455.     wMid                                        As Integer
  456.     wPid                                        As Integer
  457.     vDriverVer                                  As Long
  458.     szPname                                     As String * MAXPNAMELEN
  459.     dwFormats                                   As Long
  460.     wChannels                                   As Integer
  461.     wReserved1                                  As Integer
  462. End Type
  463.  
  464. Private Type MMTIME
  465.     wType                                       As Long
  466.     U                                           As Long
  467. End Type
  468.  
  469. Private Type WaveInBuffer
  470.     hdr                                         As WAVEHDR
  471.     intBuffer()                                 As Integer
  472.     pMem                                        As Long
  473. End Type
  474.  
  475. Private lngCurDev                               As Long
  476. Private lngBufSize                              As Long
  477. Private lngBufCnt                               As Long
  478.  
  479. Private udtBuffers()                            As WaveInBuffer
  480.  
  481. Private lngPrevProc                             As Long
  482. Private lngHwnd                                 As Long
  483.  
  484. Private hWaveIn                                 As Long
  485. Private hMixer                                  As Long
  486.  
  487. Public Event GotData( _
  488.     intBuffer() As Integer, _
  489.     lngLen As Long _
  490. )
  491.  
  492. Public Property Get IsRecording( _
  493. ) As Boolean
  494.  
  495.     IsRecording = hWaveIn <> 0
  496. End Property
  497.  
  498. ' http://www.ureader.com/message/1359669.aspx
  499. Private Function SetMixerLine2( _
  500.     ByVal devid As Long, _
  501.     ByVal index As Long _
  502. ) As Boolean
  503.  
  504.     Dim retval      As Long
  505.     Dim terr        As Long
  506.     Dim mxl         As MIXERLINE
  507.     Dim controls    As MIXERLINECONTROLS
  508.     Dim control     As MIXERCONTROL
  509.     Dim hControl    As Long
  510.     Dim pControl    As Long
  511.     Dim cd          As MIXERCONTROLDETAILS
  512.     Dim hr          As Long
  513.     Dim i           As Long
  514.     Dim c           As Long
  515.     Dim j           As Long
  516.     Dim lv          As MIXERCONTROLDETAILS_BOOLEAN
  517.     Dim hLV         As Long
  518.     Dim pLV         As Long
  519.  
  520.     mxl.cbStruct = Len(mxl)
  521.     mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN
  522.     hr = mixerGetLineInfo(devid, mxl, MIXER_GETLINEINFOF_COMPONENTTYPE)
  523.     hr = mixerGetLineInfo(devid, mxl, MIXER_GETLINEINFOF_DESTINATION)
  524.  
  525.     If (hr <> 0) Then Exit Function
  526.  
  527.     For i = 0 To mxl.dwDestination - 1
  528.         controls.cbStruct = Len(controls)
  529.         controls.dwLineID = mxl.dwLineID
  530.         controls.cControls = mxl.cControls
  531.         controls.cbmxctrl = Len(control)
  532.  
  533.         hControl = GlobalAlloc(GMEM_ZEROINIT, Len(control) * controls.cControls)
  534.         pControl = GlobalLock(hControl)
  535.  
  536.         controls.pamxctrl = pControl
  537.         controls.dwControl = MIXERCONTROL_CONTROLTYPE_MUX
  538.  
  539.         terr = mixerGetLineControls(devid, controls, MIXER_GETLINECONTROLSF_ONEBYTYPE)
  540.         If terr <> 0 Then Exit Function
  541.         CpyMem control, ByVal pControl, Len(control)
  542.         If index > control.cMultipleItems Then
  543.             GoTo SkipItem
  544.         End If
  545.  
  546.         For c = 0 To controls.cControls - 1
  547.             CpyMem control, ByVal pControl + Len(control) * c, Len(control)
  548.             If (MIXERCONTROL_CONTROLTYPE_MUX = (MIXERCONTROL_CONTROLTYPE_MUX And control.dwControlType)) Then
  549.                 cd.cbStruct = Len(cd)
  550.                 cd.dwControlID = control.dwControlID
  551.                 cd.cChannels = 1
  552.                 cd.item = control.cMultipleItems
  553.                 cd.cbDetails = Len(lv)
  554.  
  555.                 hLV = GlobalAlloc(GMEM_ZEROINIT, cd.cChannels * cd.item * cd.cbDetails)
  556.                 pLV = GlobalLock(hLV)
  557.                 
  558.                 cd.paDetails = pLV
  559.  
  560.                 terr = mixerGetControlDetails(devid, cd, MIXER_GETCONTROLDETAILSF_VALUE)
  561.  
  562.                 For j = 0 To cd.item - 1
  563.                     CpyMem lv, ByVal pLV + Len(lv) * j, Len(lv)
  564.                     If lv.fValue Then retval = i
  565.                     lv.fValue = Abs(CBool(j = index))
  566.                     CpyMem ByVal pLV + Len(lv) * j, lv, Len(lv)
  567.                 Next
  568.  
  569.                 terr = mixerSetControlDetails(devid, cd, MIXER_SETCONTROLDETAILSF_VALUE)
  570.  
  571.                 GlobalUnlock hLV
  572.                 GlobalFree hLV
  573.             End If
  574.         Next
  575.  
  576. SkipItem:
  577.         GlobalUnlock hControl
  578.         GlobalFree hControl
  579.     Next
  580.  
  581.     SetMixerLine2 = True
  582. End Function
  583.  
  584. ' http://www.ureader.com/message/1359669.aspx
  585. Private Function GetMixerLine2( _
  586.     ByVal devid As Long _
  587. ) As Long
  588.  
  589.     Dim retval      As Long
  590.     Dim terr        As Long
  591.     Dim mxl         As MIXERLINE
  592.     Dim controls    As MIXERLINECONTROLS
  593.     Dim control     As MIXERCONTROL
  594.     Dim hControl    As Long
  595.     Dim pControl    As Long
  596.     Dim cd          As MIXERCONTROLDETAILS
  597.     Dim hr          As Long
  598.     Dim i           As Long
  599.     Dim c           As Long
  600.     Dim j           As Long
  601.     Dim lv          As MIXERCONTROLDETAILS_BOOLEAN
  602.     Dim hLV         As Long
  603.     Dim pLV         As Long
  604.  
  605.     mxl.cbStruct = Len(mxl)
  606.     mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN
  607.     hr = mixerGetLineInfo(devid, mxl, MIXER_GETLINEINFOF_COMPONENTTYPE)
  608.     hr = mixerGetLineInfo(devid, mxl, MIXER_GETLINEINFOF_DESTINATION)
  609.  
  610.     If (hr <> 0) Then Exit Function
  611.  
  612.     For i = 0 To mxl.dwDestination - 1
  613.         controls.cbStruct = Len(controls)
  614.         controls.dwLineID = mxl.dwLineID
  615.         controls.cControls = mxl.cControls
  616.         controls.cbmxctrl = Len(control)
  617.  
  618.         hControl = GlobalAlloc(GMEM_ZEROINIT, Len(control) * controls.cControls)
  619.         pControl = GlobalLock(hControl)
  620.  
  621.         controls.pamxctrl = pControl
  622.         controls.dwControl = MIXERCONTROL_CONTROLTYPE_MUX
  623.  
  624.         terr = mixerGetLineControls(devid, controls, MIXER_GETLINECONTROLSF_ONEBYTYPE)
  625.         If terr <> 0 Then Exit Function
  626.  
  627.         For c = 0 To controls.cControls - 1
  628.             CpyMem control, ByVal pControl + Len(control) * c, Len(control)
  629.             If (MIXERCONTROL_CONTROLTYPE_MUX = (MIXERCONTROL_CONTROLTYPE_MUX And control.dwControlType)) Then
  630.                 cd.cbStruct = Len(cd)
  631.                 cd.dwControlID = control.dwControlID
  632.                 cd.cChannels = 1
  633.                 cd.item = control.cMultipleItems
  634.                 cd.cbDetails = Len(lv)
  635.  
  636.                 hLV = GlobalAlloc(GMEM_ZEROINIT, cd.cChannels * cd.item * cd.cbDetails)
  637.                 pLV = GlobalLock(hLV)
  638.                 
  639.                 cd.paDetails = pLV
  640.  
  641.                 terr = mixerGetControlDetails(devid, cd, MIXER_GETCONTROLDETAILSF_VALUE)
  642.  
  643.                 For j = 0 To cd.item - 1
  644.                     CpyMem lv, ByVal pLV + Len(lv) * j, Len(lv)
  645.                     If lv.fValue Then retval = j
  646.                 Next
  647.  
  648.                 GlobalUnlock hLV
  649.                 GlobalFree hLV
  650.             End If
  651.         Next
  652.  
  653. SkipItem:
  654.         GlobalUnlock hControl
  655.         GlobalFree hControl
  656.     Next
  657.  
  658.     GetMixerLine2 = retval
  659. End Function
  660.  
  661. Public Function StopRecord( _
  662. ) As Boolean
  663.  
  664.     Dim i   As Long
  665.     Dim res As Long
  666.  
  667.     If hWaveIn <> 0 Then
  668.         ' make sure all buffers are returned to us
  669.         res = waveInStop(hWaveIn)
  670.         If res <> 0 Then Debug.Print "waveInStop: " & res
  671.         res = waveInReset(hWaveIn)
  672.         If res <> 0 Then Debug.Print "waveInReset: " & res
  673.  
  674.         ' destroy all buffers
  675.         For i = 0 To lngBufCnt - 1
  676.             res = waveInUnprepareHeader(hWaveIn, _
  677.                                   udtBuffers(i).hdr, _
  678.                                   Len(udtBuffers(i).hdr))
  679.  
  680.             If res <> 0 Then Debug.Print "waveInUnprep " & i & ": " & res
  681.         Next
  682.  
  683.         res = waveInClose(hWaveIn)
  684.         If res <> 0 Then Debug.Print "waveInClose: " & res
  685.  
  686.         hWaveIn = 0
  687.     End If
  688.  
  689.     DeinitWaveInWnd
  690.  
  691.     StopRecord = True
  692. End Function
  693.  
  694. Public Function StartRecord( _
  695.     ByVal samplerate As Long, _
  696.     ByVal Channels As Integer _
  697. ) As Boolean
  698.  
  699.     Dim udtWFX  As WAVEFORMATEX
  700.     Dim res     As Long
  701.     Dim i       As Long
  702.     Dim j       As Long
  703.  
  704.     ReDim udtBuffers(lngBufCnt - 1) As WaveInBuffer
  705.  
  706.     InitWaveInWnd
  707.  
  708.     With udtWFX
  709.         .wFormatTag = WAVE_FORMAT_PCM
  710.         .nSamplesPerSec = samplerate
  711.         .nChannels = Channels
  712.         .wBitsPerSample = 16
  713.         .nBlockAlign = Channels * (.wBitsPerSample / 8)
  714.         .nAvgBytesPerSec = .nBlockAlign * .nSamplesPerSec
  715.         .cbSize = 0
  716.     End With
  717.  
  718.     res = waveInOpen(hWaveIn, lngCurDev, udtWFX, lngHwnd, 0, CALLBACK_WINDOW)
  719.     If res <> MMSYSERR_NOERROR Then
  720.         DeinitWaveInWnd
  721.         Exit Function
  722.     End If
  723.  
  724.     ' prepare headers/buffers
  725.     For i = 0 To lngBufCnt - 1
  726.         With udtBuffers(i)
  727.             ReDim .intBuffer(lngBufSize / 2 - 1) As Integer
  728.             .pMem = VarPtr(.intBuffer(0))
  729.             .hdr.dwBufferLen = lngBufSize
  730.             .hdr.lpData = .pMem
  731.             .hdr.dwUser = i
  732.  
  733.             res = waveInPrepareHeader(hWaveIn, .hdr, Len(.hdr))
  734.             If res <> MMSYSERR_NOERROR Then
  735.                 ' on error unprepare all prepared headers
  736.                 For j = (i - 1) To 0 Step -1
  737.                     waveInUnprepareHeader hWaveIn, .hdr, Len(.hdr)
  738.                 Next
  739.  
  740.                 waveInClose hWaveIn
  741.                 hWaveIn = 0
  742.  
  743.                 DeinitWaveInWnd
  744.  
  745.                 Exit Function
  746.             End If
  747.         End With
  748.     Next
  749.  
  750.     res = waveInStart(hWaveIn)
  751.     If res <> MMSYSERR_NOERROR Then
  752.         For i = 0 To lngBufCnt - 1
  753.             waveInUnprepareHeader hWaveIn, _
  754.                                   udtBuffers(i).hdr, _
  755.                                   Len(udtBuffers(i).hdr)
  756.         Next
  757.  
  758.         waveInClose hWaveIn
  759.         hWaveIn = 0
  760.  
  761.         DeinitWaveInWnd
  762.  
  763.         Exit Function
  764.     End If
  765.  
  766.     For i = 0 To lngBufCnt - 1
  767.         waveInAddBuffer hWaveIn, _
  768.                         udtBuffers(i).hdr, _
  769.                         Len(udtBuffers(i).hdr)
  770.     Next
  771.  
  772.     StartRecord = True
  773. End Function
  774.  
  775. ' number of buffers to be used for recording
  776. Public Property Get BufferCount( _
  777. ) As Long
  778.  
  779.     BufferCount = lngBufCnt
  780. End Property
  781.  
  782. Public Property Let BufferCount( _
  783.     ByVal index As Long _
  784. )
  785.  
  786.     lngBufCnt = index
  787. End Property
  788.  
  789. ' size of a buffer in bytes
  790. ' (must be multiple of 2 because we use 16 bit integers)
  791. Public Property Get BufferSize( _
  792. ) As Long
  793.  
  794.     BufferSize = lngBufSize
  795. End Property
  796.  
  797. Public Property Let BufferSize( _
  798.     ByVal bytes As Long _
  799. )
  800.  
  801.     lngBufSize = bytes
  802. End Property
  803.  
  804. Public Property Get DeviceCount( _
  805. ) As Long
  806.  
  807.     DeviceCount = waveInGetNumDevs()
  808. End Property
  809.  
  810. Public Property Get DeviceName( _
  811.     ByVal index As Long _
  812. ) As String
  813.  
  814.     Dim udtInfo As WAVEINCAPS
  815.     Dim strName As String
  816.  
  817.     waveInGetDevCaps index, udtInfo, Len(udtInfo)
  818.     strName = udtInfo.szPname
  819.  
  820.     If InStr(strName, Chr$(0)) > 0 Then
  821.         strName = Left$(strName, InStr(strName, Chr$(0)) - 1)
  822.     End If
  823.  
  824.     DeviceName = udtInfo.szPname
  825. End Property
  826.  
  827. Public Function SelectDevice( _
  828.     ByVal index As Long _
  829. ) As Boolean
  830.  
  831.     If index < 0 Or index > DeviceCount - 1 Then
  832.         Exit Function
  833.     End If
  834.  
  835.     lngCurDev = -1
  836.  
  837.     If hMixer <> 0 Then
  838.         mixerClose hMixer
  839.         hMixer = 0
  840.     End If
  841.  
  842.     mixerOpen hMixer, index, 0, 0, MIXER_OBJECTF_WAVEIN
  843.     If hMixer = 0 Then Exit Function
  844.  
  845.     lngCurDev = index
  846.  
  847.     SelectDevice = True
  848. End Function
  849.  
  850. Public Property Get MixerLineCount( _
  851. ) As Long
  852.  
  853.     Dim i   As Long
  854.  
  855.     If lngCurDev < 0 Then Exit Property
  856.  
  857.     For i = 0 To MixerDestinations(hMixer) - 1
  858.         If MixerDestinationType(hMixer, i) = MIXERLINE_COMPONENTTYPE_DST_WAVEIN Then
  859.             MixerLineCount = MixerDestinationConnections(hMixer, i)
  860.             Exit For
  861.         End If
  862.     Next
  863. End Property
  864.  
  865. Public Property Get MixerLineName( _
  866.     ByVal index As Long _
  867. ) As String
  868.  
  869.     Dim i   As Long
  870.  
  871.     If lngCurDev < 0 Then Exit Property
  872.  
  873.     For i = 0 To MixerDestinations(hMixer) - 1
  874.         If MixerDestinationType(hMixer, i) = MIXERLINE_COMPONENTTYPE_DST_WAVEIN Then
  875.             MixerLineName = MixerConnectionName(hMixer, i, index)
  876.             Exit For
  877.         End If
  878.     Next
  879. End Property
  880.  
  881. Public Function SelectMixerLine( _
  882.     ByVal index As Long _
  883. ) As Boolean
  884.  
  885.     If lngCurDev < 0 Then Exit Function
  886.  
  887.     SelectMixerLine = SetMixerLine2(hMixer, MixerLineCount - index - 1)
  888. End Function
  889.  
  890. Public Property Get SelectedDevice( _
  891. ) As Long
  892.  
  893.     SelectedDevice = lngCurDev
  894. End Property
  895.  
  896. Public Property Get SelectedMixerLine( _
  897. ) As Long
  898.  
  899.      SelectedMixerLine = MixerLineCount - GetMixerLine2(hMixer) - 1
  900. End Property
  901.  
  902. Public Property Get MixerLineType( _
  903.     Optional ByVal index As Long = -1 _
  904. ) As Long
  905.  
  906.     Dim i       As Long
  907.     Dim lngLine As Long
  908.  
  909.     If index = -1 Then
  910.         lngLine = SelectedMixerLine
  911.     Else
  912.         lngLine = index
  913.     End If
  914.  
  915.     For i = 0 To MixerDestinations(hMixer) - 1
  916.         If MixerDestinationType(hMixer, i) = MIXERLINE_COMPONENTTYPE_DST_WAVEIN Then
  917.             MixerLineType = MixerConnectionType(hMixer, i, lngLine)
  918.             Exit For
  919.         End If
  920.     Next
  921. End Property
  922.  
  923. Public Property Get MixerLineVolume( _
  924. ) As Long
  925.  
  926.     Dim i       As Long
  927.     Dim udtVol  As volume_stereo
  928.  
  929.     For i = 0 To MixerDestinations(hMixer) - 1
  930.         If MixerDestinationType(hMixer, i) = MIXERLINE_COMPONENTTYPE_DST_WAVEIN Then
  931.             udtVol = MixerConnectionVolume(hMixer, i, SelectedMixerLine)
  932.             Exit For
  933.         End If
  934.     Next
  935.  
  936.     MixerLineVolume = udtVol.L
  937. End Property
  938.  
  939. Public Property Let MixerLineVolume( _
  940.     ByVal Volume As Long _
  941. )
  942.  
  943.     Dim i       As Long
  944.     Dim udtVol  As volume_stereo
  945.  
  946.     udtVol.L = Volume
  947.     udtVol.R = Volume
  948.  
  949.     For i = 0 To MixerDestinations(hMixer) - 1
  950.         If MixerDestinationType(hMixer, i) = MIXERLINE_COMPONENTTYPE_DST_WAVEIN Then
  951.             MixerSetConnectionVolume hMixer, i, SelectedMixerLine, udtVol
  952.             Exit For
  953.         End If
  954.     Next
  955. End Property
  956.  
  957. ' subclass the created fake window
  958. Private Sub Attach( _
  959.     ByVal hWnd As Long _
  960. )
  961.  
  962.     lngHwnd = hWnd
  963.     sc_Subclass lngHwnd
  964.     sc_AddMsg lngHwnd, MM_WIM_DATA
  965. End Sub
  966.  
  967. ' remove our window proc
  968. Private Sub Detach()
  969.     If lngHwnd Then
  970.         sc_UnSubclass lngHwnd
  971.         lngHwnd = 0
  972.     End If
  973. End Sub
  974.  
  975. ' waveIn API requires either a callback or a
  976. ' window to send messages to.
  977. ' As adding a buffer to the WaveIn Queue in a
  978. ' direct callback causes a dead lock, better
  979. ' use a fake window.
  980. Private Sub InitWaveInWnd()
  981.     lngHwnd = CreateWindowEx(0&, _
  982.                              "STATIC", _
  983.                              "WAVE_IN_WINDOW", _
  984.                              0&, 0&, 0&, 0&, _
  985.                              0&, 0&, 0&, _
  986.                              App.hInstance, _
  987.                              0&)
  988.  
  989.     Attach lngHwnd
  990. End Sub
  991.  
  992. Private Sub DeinitWaveInWnd()
  993.     Detach
  994.     DestroyWindow lngHwnd: lngHwnd = 0: lngPrevProc = 0
  995. End Sub
  996.  
  997. Private Sub Class_Initialize()
  998.     lngBufCnt = 5
  999.     lngBufSize = 10& * 1024&
  1000.     lngCurDev = -1
  1001. End Sub
  1002.  
  1003. Private Sub Class_Terminate()
  1004.     If IsRecording Then
  1005.         StopRecord
  1006.     End If
  1007.  
  1008.     If hMixer <> 0 Then
  1009.         mixerClose hMixer
  1010.     End If
  1011. End Sub
  1012.  
  1013. ' /////////////////////////////////////////////////
  1014. ' ////////// WINDOWS MIXER FUNCTIONS
  1015. ' /////////////////////////////////////////////////
  1016.  
  1017. Private Property Get MixerConnectionType( _
  1018.     ByVal devid As Long, _
  1019.     ByVal destination As Long, _
  1020.     ByVal connection As Long _
  1021. ) As Long
  1022.  
  1023.     Dim udtML   As MIXERLINE
  1024.  
  1025.     udtML.cbStruct = Len(udtML)
  1026.     udtML.dwDestination = destination
  1027.     udtML.dwSource = connection
  1028.  
  1029.     mixerGetLineInfo devid, udtML, MIXER_GETLINEINFOF_SOURCE
  1030.  
  1031.     MixerConnectionType = udtML.dwComponentType
  1032. End Property
  1033.  
  1034. Private Property Get MixerDestinations( _
  1035.     ByVal deviceid As Long _
  1036. ) As Long
  1037.  
  1038.     Dim udtCaps As MIXERCAPS
  1039.  
  1040.     mixerGetDevCaps deviceid, udtCaps, Len(udtCaps)
  1041.  
  1042.     MixerDestinations = udtCaps.cDestinations
  1043. End Property
  1044.  
  1045. Private Property Get MixerConnectionName( _
  1046.     ByVal deviceid As Long, _
  1047.     ByVal destination As Long, _
  1048.     ByVal connection As Long _
  1049. ) As String
  1050.  
  1051.     Dim udtML   As MIXERLINE
  1052.  
  1053.     udtML.cbStruct = Len(udtML)
  1054.     udtML.dwDestination = destination
  1055.     udtML.dwSource = connection
  1056.  
  1057.     mixerGetLineInfo deviceid, _
  1058.                      udtML, _
  1059.                      MIXER_GETLINEINFOF_SOURCE
  1060.  
  1061.     MixerConnectionName = udtML.szName
  1062. End Property
  1063.  
  1064. Private Property Get MixerDestinationConnections( _
  1065.     ByVal deviceid As Long, _
  1066.     ByVal destination As Long _
  1067. ) As Long
  1068.  
  1069.     Dim udtML   As MIXERLINE
  1070.  
  1071.     udtML.cbStruct = Len(udtML)
  1072.     udtML.dwDestination = destination
  1073.  
  1074.     mixerGetLineInfo deviceid, _
  1075.                      udtML, _
  1076.                      MIXER_GETLINEINFOF_DESTINATION
  1077.  
  1078.     MixerDestinationConnections = udtML.cConnections
  1079. End Property
  1080.  
  1081. Private Property Get MixerDestinationType( _
  1082.     ByVal deviceid As Long, _
  1083.     ByVal destination As Long _
  1084. ) As Long
  1085.  
  1086.     Dim udtML   As MIXERLINE
  1087.  
  1088.     udtML.cbStruct = Len(udtML)
  1089.     udtML.dwDestination = destination
  1090.  
  1091.     mixerGetLineInfo deviceid, _
  1092.                      udtML, _
  1093.                      MIXER_GETLINEINFOF_DESTINATION
  1094.  
  1095.     MixerDestinationType = udtML.dwComponentType
  1096. End Property
  1097.  
  1098. Private Sub MixerSetConnectionVolume( _
  1099.     ByVal deviceid As Long, _
  1100.     ByVal destination As Long, _
  1101.     ByVal connection As Long, _
  1102.     vol As volume_stereo _
  1103. )
  1104.  
  1105.     Dim udtML   As MIXERLINE
  1106.     Dim udtMCL  As MIXERCONTROLDETAILS
  1107.     Dim CtrlID  As Long
  1108.  
  1109.     udtML.cbStruct = Len(udtML)
  1110.     udtML.dwDestination = destination
  1111.     udtML.dwSource = connection
  1112.  
  1113.     mixerGetLineInfo deviceid, udtML, MIXER_GETLINEINFOF_SOURCE
  1114.  
  1115.     CtrlID = MixerGetControlID(deviceid, _
  1116.                                udtML.dwComponentType, _
  1117.                                MIXERCONTROL_CONTROLTYPE_VOLUME, _
  1118.                                udtML.dwLineID)
  1119.  
  1120.     With udtMCL
  1121.         .cbDetails = 4
  1122.         .cbStruct = Len(udtMCL)
  1123.         .cChannels = udtML.cChannels
  1124.         .dwControlID = CtrlID
  1125.         .item = 0
  1126.         .paDetails = VarPtr(vol)
  1127.     End With
  1128.  
  1129.     mixerSetControlDetails deviceid, _
  1130.                            udtMCL, _
  1131.                            MIXER_SETCONTROLDETAILSF_VALUE
  1132. End Sub
  1133.  
  1134. Private Property Get MixerConnectionVolume( _
  1135.     ByVal deviceid As Long, _
  1136.     ByVal destination As Long, _
  1137.     ByVal connection As Long _
  1138. ) As volume_stereo
  1139.  
  1140.     Dim udtML   As MIXERLINE
  1141.     Dim udtMCL  As MIXERCONTROLDETAILS
  1142.     Dim udtVol  As volume_stereo
  1143.     Dim CtrlID  As Long
  1144.  
  1145.     udtML.cbStruct = Len(udtML)
  1146.     udtML.dwDestination = destination
  1147.     udtML.dwSource = connection
  1148.  
  1149.     mixerGetLineInfo deviceid, udtML, MIXER_GETLINEINFOF_SOURCE
  1150.  
  1151.     CtrlID = MixerGetControlID(deviceid, _
  1152.                                udtML.dwComponentType, _
  1153.                                MIXERCONTROL_CONTROLTYPE_VOLUME, _
  1154.                                udtML.dwLineID)
  1155.  
  1156.     With udtMCL
  1157.         .cbDetails = 4
  1158.         .cbStruct = Len(udtMCL)
  1159.         .cChannels = udtML.cChannels
  1160.         .dwControlID = CtrlID
  1161.         .item = 0
  1162.         .paDetails = VarPtr(udtVol)
  1163.     End With
  1164.  
  1165.     mixerGetControlDetails deviceid, _
  1166.                            udtMCL, _
  1167.                            MIXER_GETCONTROLDETAILSF_VALUE
  1168.  
  1169.     MixerConnectionVolume = udtVol
  1170. End Property
  1171.  
  1172. Private Function MixerGetControlID( _
  1173.     ByVal deviceid As Long, _
  1174.     ByVal ComponentType As Long, _
  1175.     ByVal ControlType As Long, _
  1176.     ByVal LineID As Long _
  1177. ) As Long
  1178.  
  1179.     Dim hMem     As Long
  1180.     Dim MC       As MIXERCONTROL
  1181.     Dim MxrLine  As MIXERLINE
  1182.     Dim MLC      As MIXERLINECONTROLS
  1183.  
  1184.     MxrLine.cbStruct = Len(MxrLine)
  1185.     MxrLine.dwComponentType = ComponentType
  1186.  
  1187.     If mixerGetLineInfo(deviceid, _
  1188.                         MxrLine, _
  1189.                         MIXER_GETLINEINFOF_COMPONENTTYPE) = 0 Then
  1190.  
  1191.         MLC.cbStruct = Len(MLC)
  1192.         MLC.dwLineID = LineID
  1193.         MLC.dwControl = ControlType
  1194.         MLC.cControls = 1
  1195.         MLC.cbmxctrl = Len(MC)
  1196.  
  1197.         hMem = GlobalAlloc(&H40, Len(MC))
  1198.         If hMem = 0 Then Exit Function
  1199.         MLC.pamxctrl = GlobalLock(hMem)
  1200.  
  1201.         MC.cbStruct = Len(MC)
  1202.  
  1203.         If mixerGetLineControls(deviceid, _
  1204.                                 MLC, _
  1205.                                 MIXER_GETLINECONTROLSF_ONEBYTYPE) = 0 Then
  1206.  
  1207.             CpyMem MC, ByVal MLC.pamxctrl, Len(MC)
  1208.             MixerGetControlID = MC.dwControlID
  1209.         End If
  1210.  
  1211.         GlobalUnlock hMem
  1212.         GlobalFree hMem
  1213.     End If
  1214. End Function
  1215.  
  1216.  
  1217. '-SelfSub code------------------------------------------------------------------------------------
  1218. ' by Paul Caton
  1219.  
  1220. Private Function sc_Subclass( _
  1221.     ByVal lng_hWnd As Long, _
  1222.     Optional ByVal lParamUser As Long = 0, _
  1223.     Optional ByVal nOrdinal As Long = 1, _
  1224.     Optional ByVal oCallback As Object = Nothing, _
  1225.     Optional ByVal bIdeSafety As Boolean = True _
  1226. ) As Boolean 'Subclass the specified window handle
  1227.  
  1228. '*************************************************************************************************
  1229. '* lng_hWnd   - Handle of the window to subclass
  1230. '* lParamUser - Optional, user-defined callback parameter
  1231. '* nOrdinal   - Optional, ordinal index of the callback procedure. 1 = last private method, 2 = second last private method, etc.
  1232. '* oCallback  - Optional, the object that will receive the callback. If undefined, callbacks are sent to this object's instance
  1233. '* bIdeSafety - Optional, enable/disable IDE safety measures. NB: you should really only disable IDE safety in a UserControl for design-time subclassing
  1234. '*************************************************************************************************
  1235. Const CODE_LEN      As Long = 260                                           'Thunk length in bytes
  1236. Const MEM_LEN       As Long = CODE_LEN + (8 * (MSG_ENTRIES + 1))            'Bytes to allocate per thunk, data + code + msg tables
  1237. Const PAGE_RWX      As Long = &H40&                                         'Allocate executable memory
  1238. Const MEM_COMMIT    As Long = &H1000&                                       'Commit allocated memory
  1239. Const MEM_RELEASE   As Long = &H8000&                                       'Release allocated memory flag
  1240. Const IDX_EBMODE    As Long = 3                                             'Thunk data index of the EbMode function address
  1241. Const IDX_CWP       As Long = 4                                             'Thunk data index of the CallWindowProc function address
  1242. Const IDX_SWL       As Long = 5                                             'Thunk data index of the SetWindowsLong function address
  1243. Const IDX_FREE      As Long = 6                                             'Thunk data index of the VirtualFree function address
  1244. Const IDX_BADPTR    As Long = 7                                             'Thunk data index of the IsBadCodePtr function address
  1245. Const IDX_OWNER     As Long = 8                                             'Thunk data index of the Owner object's vTable address
  1246. Const IDX_CALLBACK  As Long = 10                                            'Thunk data index of the callback method address
  1247. Const IDX_EBX       As Long = 16                                            'Thunk code patch index of the thunk data
  1248. Const SUB_NAME      As String = "sc_Subclass"                               'This routine's name
  1249.   Dim nAddr         As Long
  1250.   Dim nID           As Long
  1251.   Dim nMyID         As Long
  1252.   
  1253.     If IsWindow(lng_hWnd) = 0 Then                                            'Ensure the window handle is valid
  1254.         zError SUB_NAME, "Invalid window handle"
  1255.         Exit Function
  1256.     End If
  1257.  
  1258.     nMyID = GetCurrentProcessId                                               'Get this process's ID
  1259.     GetWindowThreadProcessId lng_hWnd, nID                                    'Get the process ID associated with the window handle
  1260.     If nID <> nMyID Then                                                      'Ensure that the window handle doesn't belong to another process
  1261.         zError SUB_NAME, "Window handle belongs to another process"
  1262.         Exit Function
  1263.     End If
  1264.   
  1265.     If oCallback Is Nothing Then                                              'If the user hasn't specified the callback owner
  1266.         Set oCallback = Me                                                      'Then it is me
  1267.     End If
  1268.   
  1269.     nAddr = zAddressOf(oCallback, nOrdinal)                                   'Get the address of the specified ordinal method
  1270.     If nAddr = 0 Then                                                         'Ensure that we've found the ordinal method
  1271.         zError SUB_NAME, "Callback method not found"
  1272.         Exit Function
  1273.     End If
  1274.     
  1275.     If z_Funk Is Nothing Then                                                 'If this is the first time through, do the one-time initialization
  1276.         Set z_Funk = New Collection                                             'Create the hWnd/thunk-address collection
  1277.         z_Sc(14) = &HD231C031: z_Sc(15) = &HBBE58960: z_Sc(17) = &H4339F631: z_Sc(18) = &H4A21750C: z_Sc(19) = &HE82C7B8B: z_Sc(20) = &H74&: z_Sc(21) = &H75147539: z_Sc(22) = &H21E80F: z_Sc(23) = &HD2310000: z_Sc(24) = &HE8307B8B: z_Sc(25) = &H60&: z_Sc(26) = &H10C261: z_Sc(27) = &H830C53FF: z_Sc(28) = &HD77401F8: z_Sc(29) = &H2874C085: z_Sc(30) = &H2E8&: z_Sc(31) = &HFFE9EB00: z_Sc(32) = &H75FF3075: z_Sc(33) = &H2875FF2C: z_Sc(34) = &HFF2475FF: z_Sc(35) = &H3FF2473: z_Sc(36) = &H891053FF: z_Sc(37) = &HBFF1C45: z_Sc(38) = &H73396775: z_Sc(39) = &H58627404
  1278.         z_Sc(40) = &H6A2473FF: z_Sc(41) = &H873FFFC: z_Sc(42) = &H891453FF: z_Sc(43) = &H7589285D: z_Sc(44) = &H3045C72C: z_Sc(45) = &H8000&: z_Sc(46) = &H8920458B: z_Sc(47) = &H4589145D: z_Sc(48) = &HC4836124: z_Sc(49) = &H1862FF04: z_Sc(50) = &H35E30F8B: z_Sc(51) = &HA78C985: z_Sc(52) = &H8B04C783: z_Sc(53) = &HAFF22845: z_Sc(54) = &H73FF2775: z_Sc(55) = &H1C53FF28: z_Sc(56) = &H438D1F75: z_Sc(57) = &H144D8D34: z_Sc(58) = &H1C458D50: z_Sc(59) = &HFF3075FF: z_Sc(60) = &H75FF2C75: z_Sc(61) = &H873FF28: z_Sc(62) = &HFF525150: z_Sc(63) = &H53FF2073: z_Sc(64) = &HC328&
  1279.  
  1280.         z_Sc(IDX_CWP) = zFnAddr("user32", "CallWindowProcA")                    'Store CallWindowProc function address in the thunk data
  1281.         z_Sc(IDX_SWL) = zFnAddr("user32", "SetWindowLongA")                     'Store the SetWindowLong function address in the thunk data
  1282.         z_Sc(IDX_FREE) = zFnAddr("kerrrrrrrrrrrrrrrrr5FF2C75:Conta        z_Sc(Iu STBUnFF525150:z_Sc(60) = &H75F'eNaludtML.cCh= zFnAddr("     zError SUB_NAME, "Wia&H4fDzFnR     As LTDE1E, "Wia&H4fDzFnR     As LTDE1E, "Wia&H4fDzFnRl_Sc(60) = &H)W"Wia&Hi = 0 To MixerDe3FF: z_Sc(43) = &H7589285D: zDtB2,8rD&HFFia&H4fDzFB25) = &H60Fiaee created fake window
  1283. Private Sceated fak st25150: z_) =  If z_rnR     As LTDE1E, "Wia&H4fDzFnR     As LTDE1E, "Wia&H4fDzFnRl_Sor  LTDE1Property
  1284.  
  1285. Publi             As Long
  1286.     szName                             Sceated fak st2he callback F631: z_Sc(18)wtm hMem     As Long
  1287.     Dim MC                       S1E, "Wia&H4fDzFnR(0: z_Sc(17) =  method
  1288. 1ng = 1ive the c collection1ng       eaaaaaaaaaaaaaaaa colleclaaa   S6*MIf terr <> 0 I=t'on1ng       eaau=_Sc(60) = &H75th
  1289.  
  1290.  pUuhing Then                                  mm MC       rsleclaaa   S6*MIf terr <> 0 I=t'on1ng   _Sc(yID = GeM    mm MC       rslecl_Sc(20) = &H7Dim MC lAs Lyate 'Th    ac(yID = GeM    mm MC       rslecl_Sc(20) = &H7Dim MC lAs Lyate 'Th    ac(yIDpH75FF3075: z_Sc(=              mm M  ac(yIDpH75FF3     rslecl_ conShod not found"erslecl_Sc(20) = &H7Dim MC lAs Lyta&H4fiC   ,FCaWFlT&H40, Len(MC))
  1291.         If                                     Dim MC lAs Lyate 'Th    ac(yID=l_Sc(20) = &H7DimWSc(e &H4589145D: z(yID=lllllllllllllllllllllllll) = n 0 I=t'on1ng   _D = GeM    mm MC       rslec04
  1292.         z_Sc(40) =  l(= indeu
  1293.    = 0 To MinutionName = udtML.szNameE8lecl_          .szNameC             _Sc(fak st2he cnR(0            _Sc(NlWrfiC   ,FCaWFlT&H40, Len(MC))
  1294.         If   iInC       rslecl_Sc(trolID(        () 0 I=t'on1ng   _D = GeM    m_D = GeM    mm MC       rslec0tz(yID=lllllllllslecic:40, Len(MC))Sc(43--------------lWrfiC   ,FCa
  1295.  
  1296. Private lngPrevProc                 either a call6ab RT&ngPrevP   mm MCfunctio--------ate lak st2he cnR(0            _Scs LyW           sh    ac(l+ss tailxlfcactio------c0tz(yI         i(yIMj          _Scs LsDim MC lAs Lyate                   sh         &H7Dim MC lAsd fak st2he callback F631: z_Sc(18)wtm hMem     As Long
  1297.     Dim MC                       S1E, "Wia&H4fDzFnR(0: z_Sc(17) =  method
  1298. 1ng = 1ive the c collection1ng       eaaaaaaaaaaaaaaaa colleclaaa   S6*MIf terr <> 0 I=t'on1ng       eaau=_Sc(60) = &H75th
  1299. Cn: a index of the S ina   S6*MIf terr <> 0 I=t'on1ng       eaau=_Sc(60) = &H75th
  1300.       ehDT ( _
  1301. ) Ashe IsH7DiT Ashe IsH7DiTr   33333333333333333333333333333333333333333333333333333333333333333333333333333333 a ,6*MIf terr <> 0 I=t'on1ng           'Release allocated memor allocated
  1302.        33333333333333       Eid, _     m,fak st2he callj lerControl fpils = pLV
  1303.  
  1304.             lerControl fpils = pLV
  1305.  
  1306.     Oe=ptional, oree hMem
  1307.     Ells = pLV
  1308.  
  1309.             lerControl fpils c(yID=lllllllllslecic:40, Len(o     lerCon
  1310.  
  1311. Publi             As Long
  1312.   lection1  = e thu
  1313.  
  1314. Publi             As Longinaonty ulecic:40, LeE_Sc(60) = &Hmemor allocaa<N   Ells       NNNNNemor alloca150: )(Is Nothing Then                emor alAl
  1315.   lectD8Control    eor allocaa<'
  1316.     If z_Funk tw hEBMODE    Aifbmhen           ection       C'
  1317.     ,pz_Sc(18)wtm hMtW = &Hmemor allocaa<N   Ells     i = =Eo'
  1318.     If z_Funk tw hEBMODE    Aifbmhen           ection FsH7DiTr   333333333333333"c(50tz(yI       iwrFunk tw hEBFunk tw hEBMODE    Aifbmhen           ecnName = ud    A       ctioE  j lerCaa colleclaa       le eitheemor alrFMODE    Ai               FrXrw               alAl
  1319.         z_R tw hEae = N            FrXlrFMODE    AS#ComctD8trtime through, do the one-tiVsFMODE   dow do the one-tiVsFMODE   dow do the one-tiVsFMODE   dow do tk tw R tw a        alAl
  1320.  returned to =t'Yol fpils = pLV2w a   h,  n <> 0the oz3TFMOT z_R tw           As Integer
  1321. End Type
  1322.  
  1323. Private Type WAVEINCAPS
  1324.     wMid                                        As Integer
  1325.     wPid                                        As Integer
  1326.     vDriverVer                                  As Long
  1327.     szPname           iAs Integer
  1328. s objec(gomm MC    gzGr                Len(udtBuffat we've 'bew
  1329.  _an) As Integer
  1330.     vDriverVer         lipsFWtl4(_an)MIhewaveInUnprepareHger
  1331.     vDriverVn    UfE       et( z_Sc(54)             As aSc(5S  &H7Dim MC lAs      As Integv         Sub
  1332. cy      As aSc(5S  &H7Dim ManR(lip  s                BMODE    )2reln      BMODE    oixer, hntegv           a,,dVDim ManR(lip  s              z_either a cal1  Oe=sD        _Scs LyW           sh    ac(l+ss tawtm hMem     As    (n  I dow deD,awtm0      H40, Len147539: z_Sc(22)E
  1333.  
  1334.     MixerConnectionTO  MixerConnectionTO  MixerConnectionT 0 Ictio  szO  )Private nnection Function(liiMIctiFun  MixerConnectioerConneetio--------ate lak st2he cnR(0 nectiA iectioonneetio--------ate ascnR(0 nectiA a2p  s(5S Aifbmhen Len(udtMCL)
  1335.         .crmhen Len(udtMCL)
  1336.    hing, _
  1337. tMC    .CDc(40) = ect nne callback F631: z_Sc(184t1n Fuyllslecic:40, LenIDX_SWL) MlCL) tw hEae = N            FrXlrFMODEn   or                Len(udtBuffat weFMO L"ntD8i) MlCL) tw h)------ate lak t As LonH75FF3075: z_Sc(=             FF3075: z_Sc(=    iI MIIIIIIII     on3075: z_Sc(=             FF3075: z_Sc(=    iI MIIIIIIId If
  1338. End    Irectiote Sub At As LY= &H891O)sgn tE'9n tawtm hMem    Buffat rectE: z_lt AsH4339F&H891O)sgn te laaaaaaT .CDc(40) = ect nne callback F631: z_Sc(184t1n Fuyllslecic:40tio=             FF3075: z_Sc(=    iI 3333333333075: z_Sc(=    iI 333333333Aa: znL    3075: z_Sc(=         FF3075: z_a  6o  szO  )Private nnection FuB: zszPname     ng
  1339. Prig
  1340. Prig
  1341. P_Utmor alloc5: z_Sc(=         FF307 s H7Dim ManAe      FF307 s H7Dim ManAe      FF307 sW Ahen           MEM rectE: z_lt As,C       _Scs LyW        n te laaa75:  _c(= LyW        n te laaa75:  _c(= LyW      d        n te laaa7IDim MC lAs          FFFFFFFFvanAe     )))))))))))))))))))cal1      FF307 sW bjec(gomm MC    gzGr     iI M_Scs LyW            n)))))cal1   rXlrFMODE    AS#l6ab RT&l)  Next
  1342.  
  1343.    t---  z_Sc     aau=_Sc(60) =W        n te   tc            cal1 z_vanAe    S#l6abv           a,,dVDim Mrloc ection FuB: zszPnaauEiACG ec       As ............  n tecti45: z_Sc(38) = &H73396775: z_Sc(39) a,,dVVVVVVV: z_Sc            FrXlrFMODE    AS#ComctD8tra= &H75F'eNa.......  n te o Buffar_)u Selet075: sEac(yID=l........  n tecti45: z_SD=l........  n tsp Ne(ng,tion FuB: zszNnneetio--)iD       FrXlrFT  contrrrrrrrrrrrrrrrtAAAAAixe6&(40) = ect lng to ano1DfOethod
  1344.     XS'pdex petsp NleAAAA hMeddress
  1345. Const IDX_EBX       As Long = 16                  m  vDri=zrmhen Len(udtMCL)
  1346.    hing, _Ano1DfOethod
  1347.     XS'pdex png(-en Len(udtMCL)
  1348.    hing, _Ano1DfOethod
  1349.     XS'pdex png(-en Len(u      n te laaa75:  _c(er
  1350.     vUBfngHwnd = 0: lngPrevProA=zrmhen Len(Bsg--  z_Sc     aau=_n tn(udtMCL)
  1351.    hing, _Ano1DfOethm MC lAs t.  n te o Buffar_)u Sel: zSel: zSel: zSel: zSel: zSel: zSel:ed to =t'Yol fpils = pLV2w nnezSel:n'Wls = pLV2w nnezSo1DfOethod
  1352.     XSezSel:eh2riverVerhe oneMCol 3Sc(C   h2ri)LV2w nne  _D = GeM    mmGMh CL)
  1353.    ose ehDT ( _
  1354. ) Ashe IsH7DiT Ashe IsH7DiTr   33333333333333333333333333333333333333333333333333333333333333333333333333333333 a ,6*MIf terr <Tr  BPtm hMem Verhe oneMCol 3Sc(C   h2ri)LV2w nne  _D =eln      BMODE   
  1355.  n Len(udt h2ri)LV2w nne  _D =eln      BMO = udt Bnne  _D =eln  L_D =eln      BMO = u53333333333333*MIf t   S6*MIf tpr32", "SetWind3Wind3pA    tpr32", "SetW ose ehDT ( _
  1356. ) Ashe IsH7DiT Ashe IsH7DiTr   3333333: z_Sc(=    iIC75:Cogundefined,  z_Sc(ID  udt333dX7DiT Ashelection1  = e ehDT (Property
  1357.  
  1358. Public Property Ashe IsB_Hbbg     udt3p = =ils = pLV2weR   A   _br   3333333: z_Sc(=    iIC75:Cogundefined,  z_Sc(ID  udt333dX7DiTV &n   nls = pLV = pLV2weR   A   _br   nlc(=    iIC75:Co(=    iIC75:ocate executabT_D =eln      n  iIC75:Co(      hCoB
  1359.   nls = pLVP u533333333"wari)LV2w nne  _D =eln      BMO 'oc ection FuB: zszPnaauEiACG ec       As ............  n tecti45   33333dtVol.L
  1360. End Propeecti45   33333dtVol.L
  1361. End Propeecti45   3unk tw hEBMODE   
  1362. End Propeecti45                            gomm MC    gzGr     iI M_Scs LyW           etd333BMODE   
  1363. Endefibrmhen Len(Bsg--  z_Sc     aau=_n tn(udtMCL)
  1364.    hing, yW      d     I  gzGr    dty Get SelectedMixerLine( _
  1365. ) As Long
  1366. (yog-- e patch lH7Dim ManR(lip  efibrmh2", ml 
  1367. Ende    gz
  1368. )on FuB: zszPnaauEiACG ec       ehDT aL5:Coon FuyWH
  1369. End Propeecti45   33333dtVol.L
  1370. End Propeecti45   3unk tw hEBMODE   
  1371. End Propeecti45                            gomm MC    gzGr     iI M_Scs LyW           etd333BMODE   
  1372. Endefibrmhen Len(Bsg--  z_Sc     aau=_n tn(udtMCL)
  1373.    hing, yW      d     I  gzGr    MSYMh
  1374.    MV2w nnezSel:  
  1375. Endefibrmhe4brmhen Len(Bsg--  z_Sc    mhe4brmhen Len(Bsg--  z_Sc    mhe4brmhen LriverVerhe                                      z_Sc                                           z_Sc               - 13333g_hWnd As Long, _
  1376.     Option(u     1,c(60) =W        n te   tc       rI    iI M_Scs n   iI M_Scs n   iI M_Scs n   iI M_Scs n   iI M_Scs pst oCallbotCS     e5   3t oCallbotCS     e5   3t oCallld Pr Ac Function Sele n   iI M_Scs le n   iI M_Scs 6Ashe IsH7DiTr   3333333: z_Sc(=    iIC75:Cogundefinedn2A   iI M_Scs pst oCallbotCS  O mhe4_c(e2Sc     a   iI MIIIIIIId                  'Ensure that n M_Scs  'Get the process ID associated with the i   FrXlrFMODE    AS#ComctD8tra= &H75F'eNa..:Coon FuyWH
  1377. End Propeecti45   33333dtVol.L
  1378. End Propeecti45 _cf n te laaa75:  __ScsiXajl    m=====================n=======vd: z_ScEs z_either a cal1  Oe=sD        _Scs La,      'EynMIf tpr3A 33333dtVol.L
  1379. End Propeecti4  iI M_Scs pst oCa
  1380.   nlsPSnWethm MC lAs t_Sc(=   L
  1381. End Propeecti4  iI M_D6iLg333333: z_Sc(36) = &H891053FF: z_S          z_  AS#Com=======vd: z_n FuyWH
  1382. EndLen(Bsg--F_   hi)on FuBW LonH75FF30000000 FuyWHnr nf n m hMem Verhe oneMCzS d        n te laaa7IDim Mblecti4lf n MCzS d        n teR    n te laaa75: IssociaBW LonH75OfO3wn te laaa7(& m Verhe o  O VerBz_either a cal1  Oe=sD        _Scs La,      'EynMIf tpr3A 33333d s  'Getpils = pLV2w nnezSel:n'Wls = pLV2w nnezSo1DfOethod
  1383.  
  1384.     End If
  1385.  
  1386. to  _Scs LaIs+c(=    iIC75:Cogundefinedn2A   iI M_Scs pst oCallbotCS  O mhe4_c(e2Sc     a   iI       he4_,-cEs z_either a cal1  Oe=sD                                efibrcal1                he4_cal1  Oe=sD                      in       laaa75:  aL5:Coon FuyWH
  1387. End Propeecti45   33333dtVol.L
  1388. End Properol for design-dCol 3udtMCL)
  1389.    hing, _Ano1DfOethod
  1390.     XS'pdex png(-engomm MC    gAs Long
  1391. Oethod
  1392.  
  1393.     End  hing, _Ano77401F8: z_Sc(29)wr
  1394. OethoCallAcdleex pngfe>lng, _Ano77        ub At As LY= &H891O)s1WetCshe IsHthoCallAcdleex pe IslAcdleex pe IslAcd gAs Lo  Ino7740isG=s N)s1WetCshUhe As LY= oF8: z_Sc(29)wr
  1395. OethoCalllAcdcOethoCalllAcdcd Propecdcg cal1  Oe=sD      N)s1WetCshUhe As LY= oF8: z_Sc(2BlllAcdcd(29, 7ecdcg cal1  Oe=sD      N)s1WetCshUhe As LAunkinaont(23) z&Scs pst oCrothod
  1396. e) z&Scs pst oCrothothod
  1397. e) z&Scs pst oCrothothoRU cal1 Scs pst oCrothothoRU cal1 Scs ge=sD                      inPr inPr inPr inPr inPr inPr inPr8sd=OfO3wninPk  'Get the LYd0ol,ltrols.dwC(=sD    nr            FrXlrFMODE    AS#ComctD8trtime through, do the o lips-tLb xerDfCS  ''''''''H
  1398. EndLen(Bsg--F_   hi)on FuBW LonH75FF3UR nr        n&a:bgh, do the o lips-LonH75OfO3rFMODxerConne onr Mh, do th         FrXlrFMODlrFM   
  1399.    hing,niol = MixerConnectiiltMODlrFM   
  1400.    hing,niol = MixerConnectiiltMODlrFOtenH75FFBW LonH75FF3U FrXlrFMODlrFM   
  1401.    hm MC       C inPr inPr in +oRU ca       NS  ''''''''H
  1402. EndLen)RU ca       NS  ''''''''H
  1403. Eback F631: z_Sc(184t1n Fuyllslec7         z_Sc                       GltMODlrFM  hN+c(bc(=    iI 3333z_Sc(184t1n Fuyllsttttttttttttttttttt am pst oCrothothoRU cal1 ScFrXlrFMODE     z_ShoRU cal13)u Selet07=ee: z yLonH333w
  1404.  i FuyWHeV    Fr
  1405. End Propeecti45   3unk tw hEB essopeecti4,4e uyllst:333w
  1406.  i FuyWHeV    Fr
  1407. End Propeecti45   3unk tw hEB essopeecti4,4e uyllst:333wt   N)s1We ov)
  1408. cy      AserConnectiiltMODlrFOtenH75FFBW   3unk tw hEB es essopeecti4,4hing, yW Proppppppppppew hEB ecy  )pLV = pLV2weR :333      S1E, "W<> rop Proppppppppppew F2ct nne callback FOBSProh''H
  1409. EndLen)RU ca       NS  ''''''''H
  1410. Eback F0H
  1411. EndLen)RU capppew Fudtk F0H
  1412. EndLen)RU capppew Fu MIXER_GETLINEINFOF_DESTINATION
  1413.  
  1414.     MixerDestinationType = udtML.dwComponen F>cy  )pLV = p: Issociam     As''''H
  1415. Eback F0HiltMODlrFOtenTrohaam     As'' = O 'oc ection ,6*MIf terr <Tr  BPtm hMem Verhe onLen)RU capppew Fudtk F0H
  1416. EndLen)RU capppew Fu MIXER_GETLINEINFOF_DESTINATION
  1417.  
  1418.     MixerDestinationType = udtML.dwComponen F>cy  )pLV = p: Issociam     As''''H
  1419. Eback F0HiltMODlrFOtenTrohaam     As'' = O 'oc ection ,6*MIf terr <Tr  BPtm hMem Verhe onLen)Rathod
  1420. e) z&Scs pst oCrothothoRU cal1 Scs pst oCrothothoRU cal1 Scs ge=sD   ATIOMIf terr)RathuF D     inPr inPiWaSPrkLen)RaothothoRU cal1 Scs pst  _o eH'ew st Bal1 ScFrXlrII     oncifiepppew Fu MIXER_GETLIoHoRU cal1 SIsH7DiTr   33333yn F>cy  )Da) z&ioe) z Nothinbbbbbbbbbbbbbbbbbbk F0HiltM(4DS17)pnPr iGETLINEINFOF_DESTIreoinbbbbbbb&Scs pst oCrothoLF0Hil.Da) z&ioe) z Nothinbbbbbbbbbbbbb   FrXlrFMODE    AS#ComctD8tra=D_
  1421. ) As z,MODINEINFOF_SOURCE
  1422.  
  1423.     MixerConnectionNamHer84t1n aER_75: z_Sc(=    iI 333333333Aa: znL    3075: z_Sc(=         FF3075: z_a  6o  szO  )Private nnection FuB: zszPname     ng
  1424. Prig
  1425. Prig
  1426. P_Utmor alloc5: z_Sc(=         FF307 s H7Dim ManAe      FF307 s H7Dim ManAe      FF307 sW Ahen           MEM rectE: z_lt As,C Ae      FF cal1 Scs gei56e     O3wn           MEM rectE: z_lt As,C AenthoEM rectE  MEM rectE: z_lt As,C AenthoEM rectAs,C Aentht        MElt As,C ADim Man 3D-rFOle is valid
  1427.         zError SUB_NAME, "Invalid window handle"
  1428.         Ex3075: z_Sc(CzS d        n te laaDiTVnnectionNamHer84t1n 75: z_a  6o  sn te laa    S+ntht       ecEndLen)RU capppew Fu MIXER_GETLINEINFOF_DESTINATION
  1429.  
  1430.     MixerDestin z_a  6oan5ialid window handle"
  1431.         ExeEIN       z_a nTO  MixerConneci._
  1432.    F cal1 Scs gei56e     O3wn           MEM rectE: z_lt As,C AenthoEM rectE  MEM retn tn(udtp_s,C AenthoEM rectE  MEM retn tn(udbTrectElcc(Czety mesctedThNXcti45:oAs LY= oF8: z_Sc(29)wr
  1433. OewerConnecMA9)wr
  1434. ani45:o    Dim MC              )6s         6*MIf te oF8: z_Sc(29)wr
  1435. OewerConnecMA9)wr
  1436. ani45:o    Dim MC    , _
  1437.     Option()wr
  1438. OewerConnecMA9)wr
  1439. ani45:o    Dim MC        MixerConnectiiltMODlr8) = &H73396775: z_Sc(39) a,,dVVVV29)wr
  1440. OewerConH75F'tha)dVVVV29)wr
  1441. OewerCoVVV29)wr
  1442. OM(M3ne As LAunkinaont(23) z&Scs pst oCrothod
  1443. e) z&Scs pst oCADiOewerCoVVV29)wr
  1444. OM(M3ne As Le LyW           sh    075Man 3D-rFOle1
  1445.  G      Ccs psorIi6en    pe IslAcdleex pe IslAcd gr
  1446. OewerCLe LyW           sDa) z&f9vnLs c(yIDV29)wr
  1447. OewerConH75F't   esDa= pGlasseM   -ntbTre)M        sD  075Man 3D-rFOle1  esirConnectiiltMNFOF_DESTINATION
  1448. A   iI M_Scs pst o_OOOOOOiew st Bal1 ScFrXlryBal1 ScFrVvTr B_NAME, C'3aINAa -ntbfEpspBoolT       R(0: z_Sc(bVV29)wr
  1449. OewerConH75F'tha)dVVVV29)wr
  1450. O    Rociated wi&H733vTr B_NAME, C'3aINAa -ntbfEpspBoolT       Rb2WD0-Sz&f9vnLs c(yb R(0:'         s psE, C'3aINAa -ntbfEpspBoolT bIE, C'3aIewerCofH75tmDestination = M retn tn(u   sD  09inbbsAonH7BnnszPnaauntbfEpspBoolT bIE, C'3aIewerCofH75tmDestiLBVVV29)wr
  1451. O    RocB) z&Scs pst oCrothothoRU calshe IslnaauntbnnszPnaauU calshe Islnaauntbnn   n&a:bgh, do the o lips-LowProcA")                   vIBB_NAME, C'3aINAa -ntbfEpspBoolT       Rb: z_Sc(2iolTst oCrothothoRU calshe s3aIewerCofHwerCoVVV29)FDVvTr B_NA'3aINAa -ntbw         vIBB_NAME, C'3aINAa -ntbfEpspBoolT       Rb: z_Sc(2iolTst oCrothothoRU calshe s3aIewerCofHwerCoVVV29)FDVvTr B_NA'3aINAa -ntbw         vIBB_NAME, C'3aINAa -ntbfEpspBoolT       Rb: z_Sc(2iolTst oCrothothoRU calshe s3aIewerCofHwerCoVVV29)FDVvTr B_NA'3aINAa -G  vIn   vIBB_NAME, C'aE ***
  1452. Const   rrCofHC'3aINApBoolTaVvTr B_NA'3aINAa -G  vIn   vIBB_NAME, C'aE **opex petsp NleAA3 owProcA")                   vIBB_NAME, C'3aINAa -ntbfEpspBoolT       Rb: z_Sc(2iolTst oCrothothoRU calshe s3aIewerCofHwerCoVVV29)FDVvTr B_NA'3aL s3aIewerCofHwerCo B_NA'3aL s3aI         75tmDestiLBVVV29)wr
  1453.     75tmDestirc "SetWind
  1454.     75tmtsp Nle5='dntbf
  1455.    A NleAA3 owProcA")                   vIBB_NAME, C'3aINAa -ntbfEpspBoolT       RbB,oVVV29)wr
  1456. OM(M3ne As LAunkinaont(23) z&S&Scs pst oCrot       s   As LAunkinaont(23) z&S&ScDestirc "SetWind  75gtrolID(        () 0 I=t'on1ngB
  1457.  
  1458.     Mixer'A'db                        S **
  1459. Const   rrC(
  1460.  
  1461.     Mixer'A'db          FrXlryBal1 ScFrVvTr B_NAME, C'3adcal1 Scs(
  1462.  
  1463.     Mixer'A'db          FrXlryBal1 Sll1 Scs ge=.z&S&ScDestirc "SetWind  75MIIIId s5bfEpspBoolT bIE, C'3aIewerCofA   0       westination l1 Sll1 Scs ge=.z&S&ScDestirc tn0 To MixerDestiFlfirc "Sn1ngB
  1464.  
  1465.  BoolT bIE, C'3aIewerCofA   0       westination l1 Sll1 Scs ge=.&ryBaMB_NA'3aL B1 Scs5fA   0   =t'on1ng   _D = (2iolinda   0       weste Islnaauntbn y_n FuyWH
  1466. EndLen(Bsg--F_   hi)on FuB  NS  ''''''''Hont&ScDestirc tn  =t'on1ng   _D = (2iolinda   0       wA'3aL s3aI   cM(2iolinda  FNatallww _D = (2iolinda   0      I333: z_tpst oCanG   )5/i45:o    Dim MC    , _
  1467.     Option B_A
  1468.    cBnaauntbfE7'rc "S9ns3aINApcdODE   
  1469.  n Len   GltMOtML)
  1470.     udtML.dwDestination = destinatiE  () 0 I=t'on1ngB
  1471.  
  1472.     Munki0              'Ensure that n M,'ibg     udt3p 6 GltMOtML)
  1473.  WWWWWWWWW PowProcA")                   vIBB_NAME, C'3aINAa -ntbfEpspBoolT       RbB,oVVV29)wr
  1474. OM(M3ne As LAunkinaont(23) z&S&Scs pst oCrot       s   As LAunkinaont(23) z&S&ScDestirc "SetWind  75gtrolID(        () 0 I=t'on1ngB
  1475.  
  1476.     Mixer'A'db                        ABB_NAME, C'3arCofA   0      me    a1ng   _D = (2)pR5       sD  075Man 3D-rFOle1  esirConnectiiltMNFOF_DESTINATION
  1477. A   iI M_Scs pst o_OOOOOOiew st Bal1 ScFrXlryBal1 ScFrVvTrAID(        () 0 I=t'3p riltOOOOiew st
  1478.  
  1479.      'rothothoRl 8F: z_Sc(39) a,,dVVVV29)wl1 ScFrXlryBal1 ScFrVvTrAID(        () 0 I=t'3p rilh ScFrXlCrothoLF0Hil.Da) z&ioe) z No     () toScDestirc "SetW      esirConnectiil= &H7Dim MC lAs Lyate 'Th  ailh 3tMOeFBW   3.8F: z_Sc(39) a,,dVVVV  'roectiiltMODlr "Seeeeeeee)OtenH75FFBW   bVVV  'roectiiltMODlr "Seeeeeeee)OtenH75FFN
  1480. ,irConnBW   bVVV  'roectiiltMODlr "Seeeeeeee)O  bVV      esirConn6iaODlrFM   
  1481.    hing,niol = Mixer(bVV29)wrrrr hinIaed= Mk.ectiiiiiBW   bVVV  'roiol = Mixer(b9)wst oCanG  'lJ0 Ashe IsH7DiT Ashe Il 'The IsH7DiT Ashe Il 'The IsH7DiT Ashe Il 'The IsH7DiT Ashe Il 'The IsH7DiT Ashe Il 'The IsH7DiT Ashe Il 'The IsH7DiT Ashe Il 'The IsH7DiT Ashe Il 'Th IlrV29)wrrrr 
  1482.     Munki0              'Ensure thatThe elinda  FNatallww _D = (2IlrV29)wrrrr 
  1483.                             YH) nTO  MixerctiiiiiBW   bVVV  'roiol = Mixer(b9)wsti, nHU'romtsp Nle5n_R tw 6s  If MixerDes'The Is  = ComponentTxerDes'The Is  = ComponentT _D VV  _D = (2ioe)wrrrr hinIaednBWntTxerDes'The Is  =  = (2ioe)
  1484.   D)7he IsH7Dnoe)wrrrr hinIC7  oCallAcdleex pngfe>lng, _Ano        SniLen(rV29)wrrrrAs LAunkinaont(23) zronentT                c As Long, _
  1485.     ByVal destinatio    Exit For
  1486.       dwCompoAcdleex pe      c As LongRe Is  =  = (2ioe)
  1487.   D)7he I Li       'Ensure thatThe +      'Ensurm2allAcdleex pngf'lODlr "Seki0             -e thatThe +      'Ensurm2allAcdleex pnBi'H 'roectiiltHaj,hOOOiew st Bal1 zronentT               s   Aongynsure thatThe +      'Ensurm2allAcdleex pngf'lODlr "Seki0             -e thatThe +      'Ensurrrrrrrrrrrrrrrrrrrrrrrrrrrrr2rrrrrrroc function address
  1488. Const IDX_SWL
  1489.  
  1490.  
  1491.  
  1492.  
  1493.  
  1494. tyilScs pst oCrothod
  1495. e) z&Scs pst oCASOe thatThe +      'Ensurrrrr,smtThB5bnoe) Sme    aA1S osTo8Nrrrrrrrrrrrrr2rrrrrrroc function asrrrrrr2rx)dVVVV29)wr
  1496. OewerCoVVV29tm3) zronentT                c As Long, uF12 +      'EnsurchctiiltMNFOF_DESTINATION
  1497.  
  1498.     udtML.dwDestination = dest    -rrre
  1499.     udtML.dwDesti  -e thatThe +      'Ensurm2allAcdleex pnBiVFLrrrrrTTINATION
  1500.  
  1501.     udtML.dwDestination = dest    -rrre
  1502.     udtML.dwDesti  -e thatThe +      'Ensurm2a  AorrrTRLINE
  1503.   4,mE em2allAcdl'Ensurm2allAC    RbB,oestoli Aso8Nrrrrrrrrrrrrr2rrrrrrroc function asrrrrrr2rx)dVVnction auti  -e thatTIsH7Dnoe)wrrrrboc function asrrrrrr2rx)dVVnction auti  -e thatTIsH7Dnoe)wrrrrboc functioC_mh2", ml 
  1504. Ende    gz
  1505. )on FuB: zszPnaauEiACG ec       ehDT2rrrrr2rnction asrrrrrr2rx)dVVnction auti  -e thatTACG ecHm Veroe)wrrrrboc fun 6s  If MixerDes'The IsRc fun 6s  If MixerDes'The IsRc fun 6s  If MixerDes'The IsRc fun 6s  If MixerD5rMrrroCroestoli Aso8Nrrrrrde    gs'The ISSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSa8IsRMt(M3ne As =6s  If MixerDeserrrrrrrrrrr  If MixerDeserrrrlBi'HAso8Nrration =xerctiiiiiBs =6 (2ioe)wOxerDesenp NleAAserrrMfunSae  If MixerDatThe +      'Ensurm2allAcdleex pnBi  iI M_ScdnBWntT18necMA9)wr
  1506. ani45:o    Dim MC E emmmm As)n tn(unfXil,lt=Aun 6s  Ierrrrrrrrrrr  If MixerDe    vII c3ti=-------------------ctioC_mh2ng,ti       SetA pnBiiF2ng,ti  =h2ng,ti     he Th'pnBi  iI M_ScdnBWe +      'Ensurm2allAcdleex pnBi   hshrrrrrrrrr  If MiB(63-------MiB(63-------tFb (63-------MiB(-tFb (63v rectE  ME4Acdm2allAcdleex pnB X63-------MiB(63-------tFb (63------Mirrr  If MixerDeserrrrlBi'HAsoaramvMiB(-tFm2allAcdleex pnG   )5/iaaaarrrrrrr,Cti  -SSSSSSSSSOewerCn1 Sll1 Scs ge=.dleex pnG   )5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5/I)5